package stocc.parser;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;

import stocc.ParserOutputHandler;
import stocc.logger.Level;
import stocc.logger.Logger;
import stocc.subject.Subject;

import com.martiansoftware.jsap.FlaggedOption;
import com.martiansoftware.jsap.JSAP;
import com.martiansoftware.jsap.JSAPException;
import com.martiansoftware.jsap.JSAPResult;
import stocc.converter.Converter;
import stocc.xml.ToXML;

public class Parse {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		ParserOutputHandler poh;
		JSAP jsap = setupJSAP();
		JSAPResult res = parseArgs(args, jsap);
		
		Logger.getLogger().setLevel(res.getString("verbosity"));
		
		//LOG
		log("started", Level.INFO);
		
		String output = res.getString("output");
		if(output.equals("XML")){
			//LOG
			log("output type: XML", Level.DEBUG);
			
			poh = new ToXML("output.xml");
		}else if(output.equals("Java")){
			log("output type: Java", Level.DEBUG);
			poh = new Converter();
		}else{
			//LOG
			log("No valid output method selected", Level.CRITICAL);
			
			System.exit(1);
			poh = new ToXML("unreachable");
		}
		try{
			//Create code parser
			CodeParser cp = new CodeParser();

			
			//List files in directory supplied
			String[] files = res.getStringArray("input");

			//Parse files given as input
			for(int i = 0; i < files.length; i++){
				Subject subject = new Subject(files[i]);
				File dir = new File(System.getProperty("user.dir") + "/" + files[i]);
				log("Loading files from: " + dir.getPath(), Level.DEBUG);
				BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(dir)));
				cp.parse(br, subject);
				poh.addSubject(subject);
			}
			poh.done();
		}catch (FileNotFoundException e){
			System.out.println("File not found");
			System.exit(0);
		}catch (CodeParser.ParsingErrorException e){
			log("Parse: Received ParsingErrorException with message: " + e.getMessage(), Level.CRITICAL);
		}
	}
	
	
	/**
	 * Logging method, add this to any class that does logging
	 * @param message The message to be logged
	 * @param level The logging level of the message
	 */
	private static void log(String message, Level level){
		Logger.getLogger().log(level, "Main", message);
	}
	
	private static JSAPResult parseArgs(String[] args, JSAP jsap){
		JSAPResult config = jsap.parse(args);
		if (!config.success()) {
            for (java.util.Iterator errs = config.getErrorMessageIterator();errs.hasNext();) {
            	System.err.println("Error: " + errs.next());
            }
			
			System.err.println();
			System.err.println("Usage: java "
					+ Parse.class.getName());
			System.err.println("                "
			        + jsap.getUsage());
			System.err.println();
			// show full help as well
			System.err.println(jsap.getHelp());
			System.exit(1);
		}
		return config;
		
	}
	
	private static JSAP setupJSAP() throws JSAPException {
		JSAP jsap = new JSAP();
		
		//Output format
		FlaggedOption f1 = new FlaggedOption("output")
			.setStringParser(JSAP.STRING_PARSER)
			.setRequired(true)
			.setShortFlag('o')
			.setLongFlag("output")
			.setUsageName("Output type [XML, JAVA]");
		jsap.registerParameter(f1);
		
		FlaggedOption f2 = new FlaggedOption("verbosity")
			.setStringParser(JSAP.STRING_PARSER)
			.setDefault("INFO")
			.setRequired(false)
			.setShortFlag('v')
			.setLongFlag("verbosity")
			.setUsageName("Logger verbosity [DEBUG, INFO, WARN, CRITICAL]");
		jsap.registerParameter(f2);
		
		FlaggedOption f3 = new FlaggedOption("input")
			.setStringParser(JSAP.STRING_PARSER)
			.setListSeparator(';')
			.setList(true)
			.setRequired(true)
			.setShortFlag('i')
			.setLongFlag("input")
			.setUsageName("semicolon-separated list of input files");
		jsap.registerParameter(f3);
		
		return jsap;
	}
	
	

}
